package com.apestech.framework.xml.sql.modul;

import com.apestech.framework.dictionary.modul.Table;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.sql.condition.FieldSql;

import java.util.ArrayList;

/**
 * @author hup
 * @create 2018-11-05-11:44
 */
public class QueryRule {
    public class ExpField{
        private String alias;
        private String field;
        private String express;
        private String sql;

        public ExpField(String alias, String field, String express, String sql){
            setField(alias, field, express, sql);
        }

        public void setField(String alias, String field, String express, String sql){
            if(alias!=null) this.alias=alias;
            if(field!=null) this.field=field;
            if(express!=null) this.express=express;
            if(sql!=null) this.sql=sql;
            if(this.express!=null) this.express=this.express.toUpperCase();
        }

        public String getAlias() {
            return alias;
        }

        public String getField() {
            return field;
        }

        public String getExpress() {
            return express;
        }

        public String getSql() {
            return sql;
        }

        public void setSql(String sql) {
            this.sql = sql;
        }
    }

    public class OutputField{
        private String field;
        private String type;
        private String format;
        private String xlsFormat;
        private String scale;

        public OutputField(String field, String type, String format, String xlsFormat, String scale){
            this.field=field;
            this.type=type;
            this.format=format;
            this.xlsFormat=xlsFormat;
            this.scale=scale;
        }

        public String getField() {
            return field;
        }

        public String getType() {
            return type;
        }

        public String getFormat() {
            return format;
        }

        public String getXlsFormat() {
            return xlsFormat;
        }

        public String getScale() {
            return scale;
        }
    }

    public class Exp{
        private String id;
        private String outerExp;  //and or
        private String innerExp;  //and or
        private ArrayList<ExpField> fields=new ArrayList<ExpField>();

        public Exp(){}

        public Exp(String id, String outerExp, String innerExp){
            setAttr(id, outerExp, innerExp);
        }

        public void setAttr(String id, String outerExp, String innerExp){
            this.id=id;
            this.outerExp=outerExp;
            this.innerExp=innerExp;
            if(this.outerExp!=null) this.outerExp=this.outerExp.toUpperCase();
            else this.outerExp="AND";
            if(this.innerExp!=null) this.innerExp=this.innerExp.toUpperCase();
            else this.innerExp="OR";
        }

        public String getId() {
            return id;
        }

        public String getOuterExp() {
            return outerExp;
        }

        public String getInnerExp() {
            return innerExp;
        }

        public ArrayList<ExpField> getFields() {
            return fields;
        }

        public void addField(String alias, String field, String express, String sql){
            fields.add(new ExpField(alias, field, express, sql));
        }

        public void setField(String alias, String field, String express, String sql){
            ExpField f=findField(alias, field);
            if(f==null) f=new ExpField(alias, field, express, sql);
            f.setField(alias, field, express, sql);
            setField(f);
        }

        private void setField(ExpField f){
            boolean flag=false;
            int len=fields.size();
            for(int i=0; i<len; i++){
                if(fields.get(i).getField().equals(f.getField())){
                    if(f.getAlias()==null && fields.get(i).getAlias()==null) flag=true;
                    else if(f.getAlias()!=null && fields.get(i).getAlias()!=null && f.getAlias().equals(fields.get(i).getAlias())) flag=true;
                    if(flag){
                        fields.set(i, f);
                        break;
                    }
                }
            }
            if(!flag) fields.add(f);
        }

        private ExpField findField(String alias, String field){
            if(fields==null) return null;
            int len=fields.size();
            for(int i=0; i<len; i++){
                if(fields.get(i).getField().equals(field)){
                    if(alias==null && fields.get(i).getAlias()==null) return fields.get(i);
                    else if(alias!=null && fields.get(i).getAlias()!=null && alias.equals(fields.get(i).getAlias()))  return fields.get(i);
                }
            }
            return null;
        }
    }

    private String from;
    private JSONObject froms=new JSONObject();
    private String autoCompletion;
    private String page;  //count 通过count语句求和 其它值为最大上限限制范围内的部分值
    private String expain;
    private String local;
    private String pageType;
    private JSONObject expjson=new JSONObject();  //key, Exp
    private JSONObject outjson=new JSONObject();  //key, Output
    private JSONObject sameas=new JSONObject();

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getAutoCompletion() {
        return autoCompletion;
    }

    public void setAutoCompletion(String autoCompletion) {
        this.autoCompletion = autoCompletion;
    }

    public String getPage() {
        return page;
    }

    public void setPage(String page) {
        this.page = page;
    }

    public String getExpain() {
        return expain;
    }

    public void setExpain(String expain) {
        this.expain = expain;
    }

    public String getLocal() {
        return local;
    }

    public void setLocal(String local) {
        this.local = local;
    }

    public String getPageType() {
        return pageType;
    }

    public void setPageType(String pageType) {
        this.pageType = pageType;
    }

    public void setBase(String from, String autoCompletion, String page, String expain, String local, String pageType){
        this.from=from;
        this.autoCompletion=autoCompletion;
        setPage(page);
        this.expain=expain;
        this.local=local;
        this.pageType=pageType;
    }

    public void setExpAttr(String id, String outerExp, String innerExp){
        Exp exp=null;
        if(expjson.get(id)!=null) exp=(Exp) expjson.get(id);
        else exp=new Exp();
        exp.setAttr(id, outerExp, innerExp);
        expjson.put(id, exp);
    }

    public void addExpField(String id, String alias, String field, String express){
        Exp exp=null;
        if(expjson.get(id)!=null) exp=(Exp) expjson.get(id);
        else exp=new Exp();
        exp.addField(alias, field, express, null);
        expjson.put(id, exp);
    }

    public Exp getExpFieldById(String id){
        if(expjson.get(id)==null) return null;
        else return (Exp) expjson.get(id);
    }

    public void addOutField(String field, String type, String format, String xlsFormat, String scale){
        OutputField out=null;
        if(outjson.get(field)!=null) out= (OutputField) outjson.get(field);
        else out=new OutputField(field, type, format, xlsFormat, scale);
        outjson.put(field, out);
    }

    public OutputField getOutById(String id){
        if(outjson.get(id)==null) return null;
        else return (OutputField) outjson.get(id);
    }

    public void setExpField(String id, String alias, String field, String express, String sql){
        Exp exp=null;
        if(expjson.get(id)!=null) exp=(Exp) expjson.get(id);
        else exp=new Exp();
        exp.setField(alias, field, express, sql);
        expjson.put(id, exp);
    }

    public void addSameas(String id, String alias){
        sameas.put(id, alias);
    }

    public JSONObject getSameas() {
        return sameas;
    }

    public ArrayList<String> getOutKeyList(){
        return outjson.getKeylist();
    }

    public ArrayList<String> getExpKeyList(){
        return expjson.getKeylist();
    }

    public void setExpField(String id, FieldSql fieldsql, Table tab) throws Exception {
        Exp exp=getExpFieldById(id);
        if(exp==null){
            setExpAttr(id, "and", "or");
        }
        setExpField(id, fieldsql.getAlais(), fieldsql.getField(), null, fieldsql.getSql().getFieldSql(fieldsql.getAlais(), fieldsql.getField(), tab));
    }

    public JSONObject getFroms() {
        return froms;
    }

    public void setFroms(JSONObject froms) {
        this.froms = froms;
    }
}
